#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <list>
#include <vector>
#include <sys/stat.h>
#include <sys/types.h>
#include <iostream>
#include <ctime>
#include "Parser.h"
#include "GeneradorDeListadoDeDirectorio.h"
#include "CompresorDeTerminos.h"
#include "QuickSort.h"
#include "SortExterno.h"
#include "SimplificadorDeTerminos.h"
#include "ResolverdorDeConsultas.h"
#include "Merge.h"


#define RUTA_TERMINOS_SIMPLIFICADOS "./Indice/simplificados.dat"
#define RUTA_INFO_DOCS "./Indice/info_docs"
#define RUTA_PUNTEROS_DOCUMENTOS "./Indice/punteros.dat"
#define RUTA_LEXICO_COMPRIMIDO "./Indice/lexico.dat"
#define RUTA_TABLA_LEXICO "./Indice/tabla.dat"
#define RUTA_DOCUMENTOS "./Indice"

using namespace std;

int main(int argc, char**argv) {
	std::string aux;

	if (argc == 1) {
		cout << "No hay párametros para iniciar la aplicacion";
		return -1;
	}
	else {
		aux = argv[1];


		if ( aux == "-i") {
			std::string destino("./Indice");
			mkdir("./Indice",S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
			int i =2;
			std::vector<std::string> lista_directorios;
			while (i < argc) {
				std::string directorio = argv[i];
				lista_directorios.push_back(directorio);
				i++;
			}
			unsigned int cantidadDeDocumentos =GeneradorDeListadoDeDirectorio::
									generarListadoDirectorios(lista_directorios, destino);
			if (cantidadDeDocumentos == 0) {
				cout << " -> Directorio inválido o vacío" << endl;
			}

			else {
				cout<<" -> Se recuperaron "<<cantidadDeDocumentos<<" documentos."<<endl;
				cout<<" -> Obtención de términos."<<endl;
				cout<<" destino "<<destino<<endl;
				Parser par;
				par.ejecutarParser(destino,destino);
				std::string pathTerminos = par.getPathTerminos();
				cout<<pathTerminos<<endl;
				cout<<" -> Ejecución de Quick Sort"<<endl;
				Termino_Parseado* terminos = 0;
				int cantidad = 0;
				SortExterno s;
				//Mientras no se termine de levantar el archivo de terminos, levanto
				//cada bloque, lo ordeno y lo grabo mediante el sort
				while (!par.levantarTerminos(pathTerminos, &cantidad, terminos)) {
					s.sort(terminos, cantidad);
					cantidad = 0;
				}

		//		cout<<" -> Ejecución de Merge."<<endl;
		//		std::list<string>particiones_generadas = s.getParticionesGeneradas();
		//		Merge::ejecutarMerge(particiones_generadas,destino);
				cout<<pathTerminos[0]<<endl;
				cout<<" -> Simplificacion de Terminos."<<endl;
				par.levantarTerminos("./Indice/particion0", &cantidad, terminos);

				SimplificadorDeTerminos simplificador;
				simplificador.set_info_docs(cantidadDeDocumentos,RUTA_INFO_DOCS);
				simplificador.simplificar(terminos,cantidad,RUTA_TERMINOS_SIMPLIFICADOS);

				cout<< " -> Compresion de Terminos" << endl;
				CompresorDeTerminos compresor(RUTA_LEXICO_COMPRIMIDO, RUTA_PUNTEROS_DOCUMENTOS, RUTA_TABLA_LEXICO);
				compresor.comprimir(RUTA_TERMINOS_SIMPLIFICADOS,RUTA_INFO_DOCS);

				cout<< " -> Indice Creado" << endl;
			}
		}

		else {
			if ( aux == "-q") {
				ResolverdorDeConsultas r(RUTA_LEXICO_COMPRIMIDO, RUTA_PUNTEROS_DOCUMENTOS, RUTA_INFO_DOCS, RUTA_TABLA_LEXICO);

				int j = 2;
				std::list<std::string> lista;
				while ( j < argc) {
					std::string termino = argv[j];
					lista.push_back(termino);
					j++;
				}
				int cantidad_devueltos= 0;
				int* ids_docs = r.consultar(lista, &cantidad_devueltos);
				RutasDocumentos rutas(RUTA_DOCUMENTOS);
				int i = 0;
				while ( i < cantidad_devueltos) {
					std::string* ruta_relevante = rutas.read(ids_docs[i]);
					std:: cout << "RUTA RELEVANTE: " << *ruta_relevante << std::endl;
					delete ruta_relevante;
					i++;
				}
				delete[] ids_docs;
			}
			else {
				cout << "Comando Inválido" << endl;
				return -1;
			}
		}
	}
	cout<<" Fin Programa"<<endl;
	return 0;
}
